package com.zll.ccp.handler;

import com.zll.ccp.annotation.RequireOwn;
import com.zll.ccp.constants.Constant;
import com.zll.ccp.mapper.*;
import com.zll.ccp.model.blog.Blog;
import com.zll.ccp.model.blog.BlogComment;
import com.zll.ccp.model.blog.BlogReply;
import com.zll.ccp.model.forum.MainPosts;
import com.zll.ccp.model.forum.MinorPosts;
import com.zll.ccp.model.forum.Theme;
import com.zll.ccp.model.pojo.ResourceType;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * 验证用户操作是否是自己资源
 * @author zll
 */
public class RequireOwnIntercepter implements HandlerInterceptor {

    @Autowired
    private IBlogMapper blogMapper;

    @Autowired
    private IBlogCommentMapper blogCommentMapper;
    @Autowired
    private IBlogReplyMapper blogReplyMapper;
    @Autowired
    private IThemeMapper themeMapper;
    @Autowired
    private IMainPostsMapper mainPostsMapper;
    @Autowired
    private IMinorPostsMapper minorPostsMapper;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            RequireOwn requireOwn = method.getDeclaredAnnotation(RequireOwn.class);
//            RequireOwn requireOwn = method.getAnnotation(RequireOwn.class);
            HttpSession session = request.getSession();
            if (requireOwn != null && !(boolean) session.getAttribute(Constant.ROLE_ADMIN)) {
                //有注解且不是管理员则需要验明正身
                //真正的身份
                String userId = (String) session.getAttribute("userId");
                String parameter = request.getParameter(requireOwn.paramName());
                String userKey = getResourceOwnId(requireOwn, parameter);
                if (!StringUtils.equals(userId, userKey)) {
                    throw new UnauthorizedException();
                }
            }
        }
        return true;
    }

    /**
     * 根据注解提供的资源类型和获取到的参数获得该资源真正拥有者的身份id
     * @param requireOwn 注解类
     * @param key 资源id
     * @return
     */
    private String getResourceOwnId(RequireOwn requireOwn,String key) {
        String userKey="";
        ResourceType resourceType = requireOwn.resourceType();
        switch (resourceType) {
            case blog:
                Blog blog = blogMapper.getBlogById(key);
                if (blog!=null){
                    userKey = blog.getUserId();
                }
                break;
            case comment:
                BlogComment blogCommentsId = blogCommentMapper.getBlogCommentsId(key);
                if (blogCommentsId!=null) {
                    userKey = blogCommentsId.getUserId();
                }
                break;
            case reply:
                BlogReply blogReplyByid = blogReplyMapper.getBlogReplyByid(key);
                if (blogReplyByid != null) {
                    userKey = blogReplyByid.getFromUserId();
                }
                break;
            case theme:
                Theme themeById = themeMapper.getThemeById(key);
                if (themeById != null) {
                    userKey = themeById.getUserid();
                }
                break;
            case main:
                MainPosts mainById = mainPostsMapper.getMainById(key);
                if (mainById!=null) {
                    userKey=mainById.getUserid();
                }
                break;
            default:
                MinorPosts minorById = minorPostsMapper.getMinorById(key);
                if (minorById!=null) {
                    userKey=minorById.getUserid();
                }
        }
        return userKey;
    }
}
